package be.fedict.eid.diagnostics.system.windows;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import be.fedict.eid.diagnostics.system.ProcessManager;
import be.fedict.eid.diagnostics.system.data.Module;
import be.fedict.eid.diagnostics.system.data.SystemProcess;
import be.fedict.eid.diagnostics.system.windows.jna.ProcessHandler;


public class WindowsProcessManager implements ProcessManager {
	
	// Internal Caching
	private Map<Module, List<SystemProcess>> moduleMap = new HashMap<Module, List<SystemProcess>>();
	private Map<SystemProcess, List<Module>> processMap = new HashMap<SystemProcess, List<Module>>();

	
	
	public Collection<SystemProcess> getProcesses() {
		List<SystemProcess> processes = null;
		if (processMap.isEmpty())
			try {
				processes = ProcessHandler.fetchProcesses();

				// Cache data
				for (SystemProcess systemProcess : processes) {
					processMap.put(systemProcess, null);
				}
				
			} catch (Exception e) {
				return null;
			}
			
		return processMap.keySet();
	}
	
	
	
	public List<Module> getModules(SystemProcess proc) {
		// first check if information has been fetched before.
		if (processMap.isEmpty()) {
			
			List<Module> modules;
			try {				
				modules = ProcessHandler.fetchModules(proc);

				// Cache data
				processMap.put(proc, modules);
				for (Module module : modules) {
					moduleUsedBy(module, proc);
				}
				
			} catch (Exception e) {
				return null;
			}
		
		}
		
		return processMap.get(proc);
	}
	
	private void moduleUsedBy(Module mod, SystemProcess proc) {
		List<SystemProcess> processList = usedByProcesses(mod);
		moduleMap.put(mod, processList);		
	}
	
	private List<SystemProcess> usedByProcesses(Module mod) {
		if (moduleMap.containsKey(mod))
			return moduleMap.get(mod);
		else
			return new Vector<SystemProcess>();
	}

	@Override
	public SystemProcess getProcess(int processId) {
		for (SystemProcess proc : processMap.keySet()) {
			if (proc.getId() == processId)
				return proc;
		}
		return null;
	}
	
}
